<HTML>

<BODY BGCOLOR="white">

<center>
<FONT SIZE=+2 COLOR="#BB0000">CS346 - Spring 2011<BR>Database System Implementation</FONT>
</center>

<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>RedBase Part 4: The Query Language Component</b></center>
<center><b>Due Sunday May 25</b></center>
</font></td></tr>
</table>

<ul>
<li> <a href="#intro">Introduction</a>
<li> <a href="#rql">The Language RQL</a>
<li> <a href="#interface"><b>QL Interface</b></a>
<li> <a href="#printing">Printing Query Plans</a>
<li> <a href="#misc">Miscellaneous</a>
<li> <a href="#doc">Documentation, Testing, Submission, Etc.</a>
</ul>

<a name="intro">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>Introduction</b></center>
</font></td></tr>
</table>

The fourth part of the RedBase system you will implement -- the last
part of the basic project -- is the <i>Query Language</i> (<i>QL</i>)
component.  This component implements the language <i>RQL</i> (for
"RedBase Query Language").  RQL's data retrieval command is a
restricted version of the SQL <tt>Select</tt> statement.  RQL's data
modification commands are restricted versions of SQL's
<tt>Insert</tt>, <tt>Delete</tt>, and <tt>Update</tt> statements.  The
public methods of the QL component are called by the RedBase parser,
similarly to the way SM component methods were called by the parser in
Part 3.  The QL component will use classes and methods from the IX,
RM, and SM components.  We'll first specify the syntax of RQL and
explain what the RQL commands should do from a user's perspective.
Then we'll specify the QL interface, which includes the methods that
support the commands.

<p><b>Warning</b> or <b>special treat</b>, depending on your
preference: Significantly more creativity and design work is required
to implement this component than any of the previous components.
We've defined the interface precisely, but there's lots to be done
underneath the interface, and there are many different ways of doing
it.  We suggest that you think very carefully and thoroughly about how
your program will operate before beginning implementation.  In
addition, if you're attempting to win the RedBase Efficiency Contest,
then this component is one of the most important and is also your last
chance!  As mentioned above, there are numerous ways of implementing
the QL interface -- some ways are much more efficient than others in
terms of I/O, so you'll want to think, design, and code carefully in
order to execute queries efficiently and best exploit the efficiency
you've already built into your previous components.

<p><b>Another warning</b>: There's so much latitude in this part of
the project, and so many techniques we've learned about in class that
could "easily" be added to the basic QL functionality, that some
students have a tendency to get overambitious.  In the extreme case --
and it does happen every year -- students set their sights so high that
they end up failing to get the basic functionality working.  Don't let
it happen to you.

<a name="rql">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>The Language RQL</b></center>
</font></td></tr>
</table>

Once the RedBase system has been started up (by issuing the
<tt>redbase</tt> command), RQL commands are recognized by the RedBase
parser just as DDL and system utility commands were recognized in Part
3.  Recall that all RedBase commands are terminated by a semicolon,
and that command keywords are case-insensitive.  Square brackets in
the syntax specifications below indicate command components that are
optional.  Because RQL is a subset of the relational query language
SQL, it is recommended that you review the SQL <tt>Select</tt>,
<tt>Insert</tt>, <tt>Delete</tt>, and <tt>Update</tt> statements in
your database textbook before beginning work on the QL component.  If
you would like to test SQL commands on a production relational DBMS in
order to compare the results with your RedBase implementation, we
recommend downloading the open-source DBMS <a
href="http://www.mysql.com/"><i>MySQL</i></a>, or using
<i>Microsoft Office Access</i> on a PC.

<h4> The RQL Select command </h4>

The syntax of the one data retrieval command in RQL is:

<pre>
Select <i>A1</i>, <i>A2</i>, ..., <i>Am</i>
From <i>R1</i>, <i>R2</i>, ..., <i>Rn</i>
[Where <i>A1'</i> <i>comp1</i> <i>AV1</i> And <i>A2'</i> <i>comp2</i> <i>AV2</i> And ... And <i>Ak'</i> <i>comp-k</i> <i>AVk</i>];
</pre>

This command has the standard SQL interpretation: The result of the
command is structured as a relation with attributes <i>A1</i>,
<i>A2</i>, ..., <i>Am</i>.  For each tuple <i>t</i> in the
cross-product of relations <i>R1</i>, <i>R2</i>, ..., <i>Rn</i> in the
<tt>From</tt> clause, if tuple <i>t</i> satisfies all conditions in
the <tt>Where</tt> clause, then the attributes of tuple <i>t</i>
listed in the <tt>Select</tt> clause are included in the result (in
the listed order).  If the <tt>Where</tt> clause is omitted, it is
considered to be <tt>true</tt> always.  Duplicate tuples in the result
are not eliminated.

<p>An alternative form of the <tt>Select</tt> command is:

<pre>
Select *
From <i>R1</i>, <i>R2</i>, ..., <i>Rn</i>
[Where <i>A1'</i> <i>comp1</i> <i>AV1</i> And <i>A2'</i> <i>comp2</i> <i>AV2</i> And ... And <i>Ak'</i> <i>comp-k</i> <i>AVk</i>];
</pre>

The interpretation of this command is the same as for the first form
of the command, except that every attribute of each satisfying tuple
<i>t</i> in the cross-product is returned.  That is, the command is
equivalent to one in which the "<tt>*</tt>" in the <tt>Select</tt>
clause is replaced by a list of all attributes of all relations
<i>R1</i>, <i>R2</i>, ..., <i>Rn</i> in the <tt>From</tt> clause.

<h4> Checks on the Select command </h4>

The parser will ensure that an RQL <tt>Select</tt> command is valid
syntactically before calling the corresponding QL component method.
In addition to requiring the basic <tt>Select-From-Where</tt> syntax
given above, the parser will ensure:

<ul>

<li> Each <i>Ai</i> in the <tt>Select</tt> clause is specified as
either <i>relName.attrName</i> or <i>attrName</i>, or the
<tt>Select</tt> list consists of the single element "<tt>*</tt>".

<p><li> Each <i>Ai'</i> in the <tt>Where</tt> clause is specified as
either <i>relName.attrName</i> or <i>attrName</i>.

<p><li> Each <i>comp-i</i> in the <tt>Where</tt> clause is one of the
comparison operators <tt>=</tt>, <tt><</tt>, <tt>></tt>, <tt><=</tt>,
<tt>>=</tt>, or <tt><></tt>.

<p><li> Each <i>AVi</i> in the <tt>Where</tt> clause is specified as
<i>relName.attrName</i> or <i>attrName</i>, or it is a constant
value.  Integer values are specified as, e.g., <tt>10</tt> or
<tt>-5</tt>, float values are specified as, e.g., <tt>3.5E-3</tt>, and
character string values are specified as, e.g., <tt>"Smith"</tt>
(don't forget the quotes).

</ul>

<p>Upon receiving a syntactically valid query, your QL component code
must perform the following semantic checks:

<ul>

<li> Each <i>Ri</i> in the <tt>From</tt> clause must name a relation
in the database.  A relation may not appear more than once in the
<tt>From</tt> clause (since RQL does not support relation variables to
distinguish multiple appearances).

<p><li> For each <i>Ai</i> = [<i>relName</i>.]<i>attrName</i> in the
<tt>Select</tt> clause, if <i>relName</i> is specified then it must be
one of the relations in the <tt>From</tt> clause.  If <i>relName</i>
is not specified, then there must be exactly one relation in the
<tt>From</tt> clause with an attribute named <i>attrName</i>.  The
same rule applies for each <i>Ai'</i> =
[<i>relName</i>.]<i>attrName</i> and each <i>AVi</i> =
[<i>relName</i>.]<i>attrName</i> in the <tt>Where</tt> clause.

<p><li> For each <i>Ai'</i> <i>comp-i</i> <i>AVi</i> in the
<tt>Where</tt> clause, the types of the two operands <i>Ai'</i> and
<i>AVi</i> must be compatible with each other.  (A discussion of type
compatibility appears in the <a href="#interface">specification of the
QL Interface</a> below.)

</ul>

Some of these checks also must be performed on <tt>Delete</tt> and
<tt>Update</tt> commands, described below.

<h4> The RQL Insert Command </h4>

Tuples may be inserted into a relation one at a time (as opposed to
bulk loading) using the following RQL command:

<pre>
Insert Into <i>relName</i> Values (<i>V1</i>, <i>V2</i>, ..., <i>Vn</i>);
</pre>

This command inserts into relation <i>relName</i> a new tuple with the
specified attribute values.  As in bulk loading, attribute values must
appear in the same order as in the "<tt>create table</tt>" command that
was executed for relation <i>relName</i>.  Values are specified in the
same way as in load files and the <tt>Select</tt> command.  String
values can be of any length up to the length specified for the
corresponding attribute.

<h4> The RQL Delete Command </h4>

Tuples may be deleted from relations using the following RQL command:

<pre>
Delete From <i>relName</i>
[Where <i>A1</i> <i>comp1</i> <i>AV1</i> And <i>A2</i> <i>comp2</i> <i>AV2</i> And ... And <i>Ak</i> <i>comp-k</i> <i>AVk</i>];
</pre>

This command deletes from relation <i>relName</i> all tuples
satisfying the <tt>Where</tt> clause.  As in the <tt>Select</tt>
command, the conditions in the <tt>Where</tt> clause compare
attributes to constant values or to other attributes.  In the
<tt>Where</tt> clause, all attributes may be specified simply as
<i>attrName</i> (since there is only one <i>relName</i>), although
specifying the <i>relName</i> is not an error.  Comparison operators
and specification of values are the same as in the <tt>Select</tt>
command.  If the <tt>Where</tt> clause is omitted, all tuples in
<i>relName</i> are deleted.

<h4> The RQL Update Command </h4>

Tuples in relations may be updated using the following RQL command:

<pre>
Update <i>relName</i>
Set <i>attrName</i> = <i>AV</i>
[Where <i>A1</i> <i>comp1</i> <i>AV1</i> And <i>A2</i> <i>comp2</i> <i>AV2</i> And ... And <i>Ak</i> <i>comp-k</i> <i>AVk</i>];
</pre>

This command updates in relation <i>relName</i> all tuples satisfying
the <tt>Where</tt> clause.  The <tt>Where</tt> clause is exactly as in
the <tt>Delete</tt> command described above.  <i>AV</i> on the
right-hand side of the equality operator is either an attribute or a
constant value.  An attribute may be specified simply as
<i>attrName</i> (since there is only one <i>relName</i>), although
specifying the <i>relName</i> is not an error.  A value is specified
as in the <tt>Select</tt> command.  Each updated tuple is modified so
that its attribute <i>attrName</i> gets the value <i>AV</i> (if
<i>AV</i> is a constant), or the value of the updated tuple's
<i>AV</i> attribute (if <i>AV</i> is an attribute).  If the
<tt>Where</tt> clause is omitted, all tuples in <i>relName</i> are
updated.

<a name="interface">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>QL Interface</b></center>
</font></td></tr>
</table>

<tt>QL_Manager</tt> is the only class in the QL interface.  It
contains four public methods, corresponding to the four RQL commands
described above.  The QL interface also includes a
<tt>QL_PrintError</tt> routine for printing messages associated with
nonzero QL return codes.  Before beginning work on the QL component
you should run the <tt>setup</tt> script with argument "<tt>4</tt>"
(for project part 4).  It will copy a simple QL tester, similar to the
one provided for the SM component, and it will recopy <tt>ql.h</tt>
and <tt>ql_manager_stub.cc</tt> so that you have the latest versions
of these files.

<p>You should rename <tt>ql_manager_stub.cc</tt> as
<tt>ql_manager.cc</tt>, then complete the implementation.  As usual,
all QL component public methods (except constructors and destructors)
should return 0 if they complete normally and a nonzero return code
otherwise.  Parser handling of nonzero return codes is exactly the
same as in Part 3: If the parser receives a nonzero return code it
will use the value of the return code to call the appropriate
component's <tt>PrintError</tt> routine.  If the return code is
positive, the parser will resume with the command loop; if the code is
negative, the parser will terminate the command loop.

<h4> QL_Manager Class </h4>

<ul>

<li> As always, all necessary component initialization should take
place within the constructor for the <tt>QL_Manager</tt> class, and
all "cleanup" should take place within its destructor.

<p><li> When implementing the public methods of the <tt>QL_Manager</tt>
class, in addition to adhering to the method descriptions below,
please refer to the RQL command descriptions given above.

<p><li> If you treated user-specified names as case-sensitive
(respectively, case-insensitive) in the SM component, then you should
probably continue to do the same in this component.  As in the SM
component, all user-specified names are passed from the parser exactly
as they are typed by the user.

<p><li> The SM component interface from Part 3 exports the methods
that implement the RedBase DDL and system utility commands, along with
methods <tt>OpenDb</tt> and <tt>CloseDb</tt>.  In the QL component you
will almost certainly find a need to use other functionality you
implemented in Part 3; surely you will at least need to obtain schema
information from the system catalogs <tt>relcat</tt> and
<tt>attrcat</tt>.  Consequently, in order to implement Part 4, you
will probably need to allow the QL component to access some classes
and methods that you may have treated as private in the SM component
for Part 3.  (Depending on how you implemented SM, you may even find
it convenient to enhance the SM component to some extent, for
convenience in implementing QL methods.)

<p><li> As usual, you are free to extend the QL interface if you find it
convenient, although you should not modify the existing methods since
they are called by the parser as specified.

<p><li> All printing of relations (including query answers) in this
component <i>must</i> be done through the <tt>Printer</tt> class we
provided with the SM component.  Please do not alter the way you print
tuples or relations -- our test suite depends on conformance.

<p><li> Values passed to QL component methods are handled as follows.
The parser recognizes whether it is reading an integer, a float, or a
string.  It converts the input to the appropriate type; then when it
calls the QL component method it passes a structure that contains the
type of the value along with a pointer to the value cast as <tt>(void
*)</tt>.  The type information allows you to check that the type of the
value is the type expected (based on schema information), and you will
need to cast the value back from <tt>(void *)</tt> to its appropriate
type.

<p><li> In attribute-constant and attribute-attribute comparisons, you
are not required to perform coercion so that integers and floats can
be compared, but you are welcome to do so if you wish.  For
strings, you should permit the case where the two values being
compared are strings of different length.  You can do so by
null-terminating or null-padding the shorter one.

<p><li> Before specifying the interface for the <tt>QL_Manager</tt>
class, we define several structures that are used in passing
parameters from the parser to <tt>QL_Manager</tt> methods.  These
structures are defined in <tt>parser.h</tt>.  The <tt>ostream</tt>
operator in each of these structures is provided so that structure
values can be sent to standard output for debugging purposes (i.e., by
writing "<tt>cout &lt;&lt; &lt;object&gt;;</tt>").

</ul>

<pre>
struct RelAttr {
  char *relName;     // relation name (may be NULL) 
  char *attrName;    // attribute name              
  friend ostream &operator<<(ostream &s, const RelAttr &ra);
};

struct Value {
  AttrType type;     // type of value               
  void     *data;    // value                       
  friend ostream &operator<<(ostream &s, const Value &v);
};

struct Condition {
  RelAttr lhsAttr;      // left-hand side attribute                     
  CompOp  op;           // comparison operator                          
  int     bRhsIsAttr;   // TRUE if right-hand side is an attribute
                        //   and not a value
  RelAttr rhsAttr;      // right-hand side attribute if bRhsIsAttr = TRUE
  Value   rhsValue;     // right-hand side value if bRhsIsAttr = FALSE
  friend ostream &operator<<(ostream &s, const Condition &c);
};

class QL_Manager {
 public:
                                              // Constructor
      QL_Manager (SM_Manager &smm, IX_Manager &ixm, RM_Manager &rmm);
      ~QL_Manager ();                         // Destructor
   RC Select (int           nSelAttrs,        // # attrs in Select clause
              const RelAttr selAttrs[],       // attrs in Select clause
              int           nRelations,       // # relations in From clause
              const char * const relations[], // relations in From clause
              int           nConditions,      // # conditions in Where clause
              const Condition conditions[]);  // conditions in Where clause
   RC Insert (const char  *relName,           // relation to insert into
              int         nValues,            // # values to insert
              const Value values[]);          // values to insert
   RC Delete (const char *relName,            // relation to delete from
              int        nConditions,         // # conditions in Where clause
              const Condition conditions[]);  // conditions in Where clause
   RC Update (const char *relName,            // relation to update
              const RelAttr &updAttr,         // attribute to update
              const int bIsValue,             // 0/1 if RHS of = is attribute/value
              const RelAttr &rhsRelAttr,      // attr on RHS of =
              const Value &rhsValue,          // value on RHS of =
              int   nConditions,              // # conditions in Where clause
              const Condition conditions[]);  // conditions in Where clause
};
</pre>

<h4>
RC Select (int nSelAttrs, const RelAttr selAttrs[],
           int nRelations, const char * const relations[],
           int nConditions, const Condition conditions[])
</h4>

The six arguments to this method logically comprise three pairs.  The
first argument of each pair is an integer <i>n</i> indicating the
number of items in the second argument of the pair.  The second
argument is an array of length <i>n</i> containing the actual items.
For example, argument <tt>nSelAttrs</tt> contains the number of
selected attributes, while argument <tt>selAttrs</tt> is an array of
length <tt>nSelAttrs</tt> containing the actual attributes.  (A single
attribute with string value "*" is passed for "<tt>Select *</tt>"
queries.)  The same approach is used for variable-length argument
lists in other methods of the <tt>QL_Manager</tt> class.

<p>Method <tt>QL_Manager::Select</tt> contains the core of the work
you will do for the QL component.  The main requirement is that when
the user enters a valid RQL <tt>Select</tt> command, sooner or later
the correct result according to the semantics described above should
print on the screen.  There are many options you will need to consider
when implementing this method; some design requirements and
suggestions follow.

<p>Your implementation should build a query tree, which will first
serve as your logical query plan and then will be transformed into a
physical plan.  We strongly suggest using an iterator approach for
plan execution, although you may use a temporary relation approach
instead if you have valid reasons for doing so.

<p>Regardless of other design decisions you make, we would like your
query execution strategy to be able to take advantage of indexes
whenever it is (relatively) straightforward to do so.  In particular:

<ul>

<li> Suppose the query includes a local selection condition of the
form <i>R.A</i><tt>=</tt><i>v</i>, where <i>v</i> is a constant value.
If relation <i>R</i> has an index on attribute <i>A</i>, then an IX
component index scan together with calls to method
<tt>RM_FileHandle::GetRec</tt> can be used to fetch the tuples of
<i>R</i>, rather than using an RM component file scan.  (Hereafter, we
use "index scan" to mean an IX component condition-based scan together
with tuple fetching, and "file scan" to mean an RM component scan.)

<p><li> You may use a simple nested-loop algorithm for each join or
cross-product.  Suppose you are joining <i>R</i> with <i>S</i> based
on attribute equality, suppose <i>S</i> has no local selection
condition, and suppose <i>S</i> has an index on its join attribute
<i>A</i>.  Then you can make <i>S</i> the inner relation of the
nested-loop join and use an index scan on <i>S</i> instead of a file
scan.  (You need not, however, attempt to reorder the relations in the
query in order to make such index joins possible.)

</ul>

When returned to the user, a query result should look like a relation:
a header, followed by a set of tuples, followed by a summary of the
number of tuples returned.  <i>You must use the</i> <tt>Printer</tt>
<i>class we provided in project part 3 to print RQL query results.</i>

<h4>
RC Insert (const char *relName, int nValues, const Value values[])
</h4>

This method should create a new tuple in relation <tt>*relName</tt>
with the specified attribute values.  Your code should confirm that
the number and type of values in arguments <tt>nValues</tt> and
<tt>values</tt> matches the schema of the relation.  This method
should construct the tuple, call method
<tt>RM_FileHandle::InsertRec</tt> to insert the tuple, then call
method <tt>IX_IndexHandle::InsertEntry</tt> for each index to create
appropriate index entries for the tuple.  To provide feedback to the
user, this method should also print the inserted tuple on the screen
(using the <tt>Printer</tt> class).

<h4>
RC Delete (const char *relName, int nConditions, const Condition conditions[])
</h4>

This method should delete all tuples in relation <tt>*relName</tt>
that satisfy the specified conditions.  If there are no conditions,
then this method should delete all tuples in <tt>*relName</tt>.  (Note
that even if all tuples are deleted, the relation should not be
destroyed, it should just become empty.)  Recall that within argument
<tt>conditions</tt>, attributes may be specified by attribute name
only (i.e., <tt>relName</tt> may be <tt>NULL</tt> in <tt>RelAttr</tt>
structures), since there is only one relation involved.

<p>Any number of conditions is allowed.  Let <i>R</i> be relation
<tt>*relName</tt>, suppose there is a condition of the form
<i>R.A</i><tt>=</tt><i>v</i> where <i>v</i> is a constant value, and
suppose <i>R</i> has an index on attribute <i>A</i>. Then you can use
an index scan to efficiently fetch those tuples of <i>R</i> satisfying
<i>R.A</i><tt>=</tt><i>v</i>.  For each fetched tuple, check the
remaining conditions and, if they are all satisfied, delete the tuple.
If there is no condition with an appropriate index, then a file scan
should be used.  Each tuple is fetched, the conditions are checked,
and if satisfied the tuple is deleted.  Don't forget to delete
corresponding index entries when you delete a tuple.

<p>Although the execution strategies for <tt>Delete</tt> commands
generally are simpler than for <tt>Select</tt> commands, you should
still build physical query plans for <tt>Delete</tt>.  You will
probably find that some physical operators from your implementation of
<tt>Select</tt> can be reused.

<p>To provide feedback, this method should print the deleted tuples on
the screen (using the <tt>Printer</tt> class).

<h4>
RC Update (const char *relName, const RelAttr &updAttr,       
           const int bIsValue, const RelAttr &rhsRelAttr,    
           const Value &rhsValue, int nConditions, const Condition conditions[]);
</h4>

This method should update all tuples in relation <tt>*relName</tt>
that satisfy the specified conditions, setting the value of attribute
<tt>*updAttr</tt> in each updated tuple to a new value.  If
<tt>bIsValue=1</tt> then the new updated value should be the constant
in <tt>rhsValue</tt>, otherwise the new updated value should be taken
from the attribute specified by <tt>rhsRelAttr</tt>.  If there are no
conditions, then this method should update all tuples in
<tt>*relName</tt>.  Conditions are exactly as in method
<tt>QL_Manager::Delete</tt>.  You can use the same strategy for
exploiting an index in this method as was described for
<tt>QL_Manager::Delete</tt>, with one important exception: don't scan
an index on the attribute being updated unless you have accounted for
this case in your IX component!  If you are updating an indexed
attribute, don't forget to delete and then insert index entries for
each updated tuple.  You should build physical query plans for
<tt>Update</tt> commands, and again you will probably find that you
can use reuse previously implemented physical operators.  To provide
feedback, this method should print the updated tuples on the screen
(using the <tt>Printer</tt> class).

<h4> QL_PrintError </h4>

<h4>
void QL_PrintError (RC rc);
</h4>

This routine should write a message associated with the nonzero QL
return code <tt>rc</tt> onto the Unix <tt>stderr</tt> output stream.
This routine has no return value.  As in the SM component, you should
not call <tt>QL_PrintError</tt> directly from within the QL (or any
other) component.  <tt>QL_PrintError</tt> is called automatically by
the parser when it receives a nonzero return code from an SM component
method it invokes.

<a name="printing">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>Printing Query Plans</b></center>
</font></td></tr>
</table>

Your implementations of the RQL <tt>Select</tt>, <tt>Delete</tt>, and
<tt>Update</tt> commands should ultimately build a physical query plan
before actually executing the query.  Query plans are not required for
<tt>Insert</tt> commands.  Your system should provide a way to
pretty-print physical query plans for <tt>Select</tt>,
<tt>Delete</tt>, and <tt>Update</tt> commands before the command is
executed.  You will probably want to render tree-structured plans
using some form of indentation.

<p>Query plans should be printed only when the value of special global
variable <tt>bQueryPlans</tt> is 1.  Two administrative commands are
provided in the parser for toggling the <tt>bQueryPlans</tt> variable:

<p>
<table border=1>
<tr><td> <tt>queryplans on;</tt>      <td> Turn on the display of query plans
<tr><td> <tt>queryplans off;</tt>     <td> Turn off the display of query plans
</table>

<p>
You must <tt>#include "parser.h"</tt> in <tt>ql_manager.cc</tt>, or
any other files that access the <tt>bQueryPlans</tt> variable.

<p>For full credit in this component of the project, the TA must be
able to easily understand your query execution strategy for any RQL
<tt>Select</tt>, <tt>Delete</tt>, or <tt>Update</tt> command based
upon the pretty-printed plan information.  But again, please do
<i>not</i> print plans unless variable <tt>bQueryPlans</tt> is set.

<a name="misc">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>Miscellaneous</b></center>
</font></td></tr>
</table>

<ul>

<li> If you have been following our suggestions, then the system
catalog relations <tt>relcat</tt> and <tt>attrcat</tt> will be open at
all times during a RedBase session, and these relations will be the
only ones left open when a command is not underway.  You should allow
RQL data retrieval commands to be performed on system catalogs.  As
with the <tt>help</tt> and <tt>print</tt> utilities in the SM
component, you may want to force to disk the files containing a
catalog before executing an RQL query over it, unless you have adopted
a policy of forcing catalogs whenever they are modified.  Users should
not be permitted to modify system catalogs using RQL commands.

<p><li> When implementing the nested-loop join operator as an iterator,
do not open and close the RM file for the inner relation on each
open/close iterator call, since all pages are flushed from the buffer
when a file is closed.  Instead, create one <tt>RM_FileHandle</tt> and
use it to make repeated RM file scans.

</ul>

<a name="doc">
<p>
<table border=0 cellpadding=4 cellspacing=10 width="100%">
<tr><td width="100%" bgcolor="#ccccff"><font face="Arial">
<center><b>Documentation, Testing, Submission, Etc.</b></center>
</font></td></tr>
</table>


<ul>

<li> The requirements for documentation and the method of submission
are the same as for previous project parts, including citing in your
<tt>ql_DOC</tt> file any assistance that you received on this
component.  In this submission please remember to include all updated
source files and the three executables: <tt>redbase</tt>,
<tt>dbcreate</tt>, and <tt>dbdestroy</tt>.  All executables that you
turn in must be compiled with <b>statistics
on</b>.

<p><li> Remember to thoroughly test your system with large relations
and complex queries and updates.  (For example, we strongly suggest
that you devise your own data in addition to the data provided in our
sample files.)  As usual, we will conduct tests of our own during the
grading process.

<p><li> At the same time that we test each student's QL component for
grading purposes, we will be benchmarking each student's complete
system to determine the winners of the efficiency contest.  If you
prefer that we <i>not</i> benchmark your system for the contest,
please notify the TA.

</ul>


</BODY>

